class_name Player extends CharacterBody2D


signal died


const MAX_HEALTH: int = 10


var multiplayer_id: int


@export_range(0, MAX_HEALTH) var health: int = 10:
	get:
		return health
	set(new_value):
		var new_health: int = clampi(new_value, 0, MAX_HEALTH)
		if health > 0 and new_health == 0:
			died.emit()
			_shoot_timer.stop()
			set_physics_process(false)
		health = new_health
		update_health_label()
		
@export var number_of_coins: int = 0:
	get:
		return number_of_coins
	set(new_value):
		number_of_coins = clampi(new_value, 0, new_value)
		update_coins_label()
		
@export var damage: float = 0.0
@export var player_name: String = "Erika"
@export var max_speed: float = 500.0
@export var acceleration: float = 2500.0
@export var deceleration: float = 1500.0
@export var projectile_scene: PackedScene = preload("res://parts/projectile/projectile.tscn") as PackedScene
@export var shoot_distance: float = 400.0


@onready var health_label: Label = $HealthLabel as Label
@onready var coins_label: Label = $CoinsLabel as Label
@onready var _shoot_timer: Timer = $ShootTimer as Timer
@onready var _camera_position: Node2D = $CameraPosition as Node2D


func add_health_points(diffrence: int):
	health += diffrence
	

func update_health_label():
	if not is_instance_valid(health_label):
		return
	health_label.text = "{0}/{1}".format([ health, MAX_HEALTH])
	
func add_coins_points(diffrence: int):
	number_of_coins += diffrence
	

func update_coins_label():
	if is_instance_valid(coins_label):
		coins_label.text = str(number_of_coins)
		
		
func get_hit():
	health -= 1
	

# Called when the node enters the scene tree for the first time.
func _ready() -> void:
	update_health_label()
	update_coins_label()
	if not multiplayer.is_server():
		_shoot_timer.stop()
	if not is_multiplayer_authority():
		_camera_position.queue_free()
		set_physics_process(false)
		#set_process(false)


func _enter_tree() -> void:
	set_multiplayer_authority(multiplayer_id)
	$HealthMultiplayerSynchronizer.set_multiplayer_authority(1)


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _physics_process(delta: float) -> void:
	var input_direction: Vector2 = Input.get_vector("move_left", "move_right", "move_up", "move_down")
	if input_direction != Vector2.ZERO:
		velocity = velocity.move_toward(input_direction * max_speed, acceleration * delta)
	else:
		velocity = velocity.move_toward(Vector2.ZERO, deceleration * delta)
	move_and_slide()


func _on_shoot_timer_timeout() -> void:
	var closet_enemy: Enemy = _find_closet_enemy_in_range()
	if not is_instance_valid(closet_enemy):
		return
	var new_projectile: Projectile = projectile_scene.instantiate() as Projectile
	new_projectile.target = closet_enemy
	get_parent().add_child(new_projectile, true)
	new_projectile.global_position = global_position
	
	
func _find_closet_enemy_in_range() -> Enemy:
	var closet_enemy: Enemy = null
	var smallest_distance: float = INF
	var enemies: Array = get_tree().get_nodes_in_group("enemy")
	if enemies.is_empty():
		return closet_enemy
	for enemy in enemies:
		var distance_to_enemy: float = global_position.distance_to(enemy.global_position)
		if distance_to_enemy < smallest_distance:
			closet_enemy = enemy
			smallest_distance = distance_to_enemy
	if smallest_distance <= shoot_distance:
		return closet_enemy
	else:
		return null
